home *** CD-ROM | disk | FTP | other *** search
/ Assassins - Ultimate CD Games Collection 4 / Assassins 4 (1999)(Weird Science).iso / misc / omega / source / effect3.c < prev    next >
C/C++ Source or Header  |  1997-05-02  |  32KB  |  1,213 lines

  1. /* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */
  2. /* effect3.c */
  3.  
  4. #include "glob.h"
  5.  
  6. /* if know id, then summon that monster; else (if < 0) get one. */
  7. void summon(blessing,id)
  8. int blessing,id;
  9. {
  10.   int i,looking=TRUE,x,y;
  11.   pml tml;
  12.  
  13.   if (id < 0) {
  14.     if (blessing > 0) {
  15.       id = monsterlist();
  16.       xredraw();
  17.     }
  18.     /* for (id ==0) case, see below -- get a "fair" monster */
  19.     else if (blessing < 0) id = random_range(NUMMONSTERS);
  20.   }
  21.   for(i=0;((i<8) && looking);i++) {
  22.     x = Player.x+Dirs[0][i];
  23.     y = Player.y+Dirs[1][i];
  24.     looking = ((! inbounds(x,y)) ||
  25.            (Level->site[x][y].locchar != FLOOR) ||
  26.            (Level->site[x][y].creature != NULL));
  27.   }
  28.  
  29.   if (! looking) {
  30.     if ((blessing == 0) && (id < 0))
  31.       Level->site[x][y].creature = m_create(x,y,WANDERING,difficulty());
  32.     else Level->site[x][y].creature = make_creature(id);
  33.     Level->site[x][y].creature->x = x;
  34.     Level->site[x][y].creature->y = y;
  35.     tml = ((pml) checkmalloc(sizeof(mltype)));
  36.     tml->m = Level->site[x][y].creature;
  37.     if (blessing > 0)
  38.       m_status_reset(tml->m,HOSTILE);
  39.     else if (blessing < 0)
  40.       m_status_set(tml->m,HOSTILE);
  41.     tml->next = Level->mlist;
  42.     Level->mlist = tml;
  43.   }
  44. }
  45.  
  46.  
  47.  
  48. int itemlist(itemindex,num)
  49. int itemindex,num;
  50. {
  51.   int i,itemno;
  52.  
  53.   print2("Show ID list? ");
  54.   if (ynq2() == 'y') {
  55.     menuclear();
  56.     for(i=0;i<num;i++) {
  57.       menunumprint(i+1);
  58.       menuprint(":");
  59.       menuprint(Objects[i+itemindex].truename);
  60.       menuprint("\n");
  61.     }
  62.     showmenu();
  63.   }
  64.   mprint("Item ID? ");
  65.   itemno = (int) parsenum()-1;
  66.   if ((itemno >= num)||(itemno<0)) itemno = ABORT;
  67.   return(itemno);
  68. }
  69.  
  70. int monsterlist()
  71. {
  72.   int i,itemno;
  73.   print2("Show ID list? ");
  74.   if (ynq2() == 'y')
  75.     do {
  76.       clearmsg();
  77.       print1("Summon monster: ");
  78.       menuclear();
  79.       for(i=0;i<NUMMONSTERS;i++) {
  80.     menunumprint(i+1);
  81.     menuprint(":");
  82.     menuprint(Monsters[i].monstring);
  83.     menuprint("\n");
  84.       }
  85.       showmenu();
  86.       itemno = (int) parsenum()-1;
  87.       if ((itemno < 0) || (itemno > NUMMONSTERS-1)) {
  88.     print3("How about trying a real monster?");
  89.     morewait();
  90.       }
  91.     } while ((itemno < 0) || (itemno > NUMMONSTERS-1));
  92.   else
  93.     do {
  94.       print1("Summon monster: ");
  95.       itemno = (int) parsenum()-1;
  96.     } while ((itemno < 0) || (itemno > NUMMONSTERS-1));
  97.   return(itemno);
  98. }
  99.       
  100.  
  101.  
  102. /* uncurse all items, cure diseases, and neutralize poison */
  103. void cleanse(blessing)
  104. int blessing;
  105. {
  106.   int i;
  107.  
  108.   if (blessing > -1) {
  109.     if (blessing > 0)
  110.       for(i=0;i<MAXITEMS;i++) 
  111.     if (Player.possessions[i] != NULL) {
  112.       if ((Player.possessions[i]->used) &&
  113.           (Player.possessions[i]->blessing < 0)) {
  114.         Player.possessions[i]->used = FALSE;
  115.         item_use(Player.possessions[i]);
  116.         Player.possessions[i]->blessing = 0;
  117.         Player.possessions[i]->used = TRUE;
  118.         item_use(Player.possessions[i]);
  119.       }
  120.     }
  121.     
  122.     if (Player.status[POISONED] > 0) {
  123.       Player.status[POISONED] = 0;
  124.     }
  125.     if (Player.status[DISEASED] > 0) {
  126.       Player.status[DISEASED] = 0;
  127.     }
  128.     showflags();
  129.     mprint("You feel radiant!");
  130.   }
  131.   else {
  132.     Player.status[POISONED] += 10;
  133.     Player.status[DISEASED] += 10;
  134.     mprint("You feel besmirched!");
  135.     showflags();
  136.   }
  137. }
  138.  
  139. void annihilate(blessing)
  140. int blessing;
  141. {
  142.   pml ml;
  143.   int i;
  144.  
  145.   if (blessing == 0) {
  146.     mprint("Lightning strikes flash all around you!!!");
  147.     for(i=0;i<9;i++)
  148.       if (Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].creature !=
  149.       NULL)
  150.     m_death(Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].creature);
  151.   }
  152.   if (blessing > 0) {
  153.     if (Current_Environment == E_COUNTRYSIDE) {
  154.     clearmsg();
  155.     print1("A thousand bolts of lightning flash down for as far as you can see!!!");
  156.     morewait();
  157.     print1("There is a rain of small birds and insects from the sky, and you");
  158.     print2("notice that you can't hear any animal noises around here any more...");
  159.     Player.alignment -= 3;
  160.     }
  161.     else {
  162.       mprint("A thousand bolts of lightning flash throughout the level!!!");
  163.       for(ml=Level->mlist;ml!=NULL;ml=ml->next)
  164.     if (ml->m != NULL && ml->m->hp > 0)
  165.       m_death(ml->m);
  166.     }
  167.   }
  168.   else {
  169.     mprint("You are hit by a bolt of mystic lightning!");
  170.     p_death("self-annihilation");
  171.   }
  172. }
  173.  
  174.  
  175.  
  176.  
  177. void sleep_monster(blessing)
  178. int blessing;
  179. {
  180.   pml ml;
  181.   int x=Player.x,y=Player.y;
  182.   struct monster *target;
  183.  
  184.   if (blessing == 0) setspot(&x,&y);
  185.  
  186.   if (blessing < 0)
  187.     sleep_player(abs(blessing)+2);
  188.   else if (blessing > 0) {
  189.     mprint("A silence pervades the area.");
  190.     for (ml=Level->mlist;ml!=NULL;ml=ml->next) {
  191.       m_status_reset(ml->m,AWAKE);
  192.       ml->m->wakeup = 0;
  193.     }
  194.   }
  195.   else {
  196.     target = Level->site[x][y].creature;
  197.     if (target != NULL) {
  198.       if (target->uniqueness == COMMON) {
  199.     strcpy(Str1,"The ");
  200.     strcat(Str1,target->monstring);
  201.       }
  202.       else strcpy(Str1,target->monstring);
  203.       if (! m_immunityp(target,SLEEP)) {
  204.     strcat(Str1," seems to have fallen asleep.");
  205.     m_status_reset(target,AWAKE);
  206.     target->wakeup = 0;
  207.       }
  208.       else strcat(Str1," is bright eyed, and bushy tailed!");
  209.       mprint(Str1);
  210.     }
  211.     else mprint("Nothing to sleep there!");
  212.   }
  213. }
  214.   
  215. void sleep_player(amount)
  216. int amount;
  217. {
  218.   if (Player.status[SLEPT] == 0) { /* prevent player from sleeping forever */
  219.     mprint("You feel sleepy...");
  220.     if (! p_immune(SLEEP)) {
  221.       Player.status[SLEPT] += random_range(amount*2)+2;
  222.     }
  223.     else mprint("but you shrug off the momentary lassitude.");
  224.   }
  225. }
  226.  
  227.  
  228. void hide(x,y)
  229. int x,y;
  230. {
  231.   if (inbounds(x,y)) {
  232.     lset(x,y,SECRET);
  233.     lset(x, y, CHANGED);
  234.     putspot(x, y, WALL);
  235.     mprint("You feel sneaky.");
  236.   }
  237. }
  238.  
  239. void clairvoyance(vision)
  240. int vision;
  241. {
  242.   int i,j;
  243.   int x = Player.x, y = Player.y;
  244.   mprint("Clairvoyance... ");
  245.   setspot(&x,&y);
  246.   for(i=x-vision;i<x+vision+1;i++)
  247.     for(j=y-vision;j<y+vision+1;j++) {
  248.       if (inbounds(i,j)) {
  249.     Level->site[i][j].showchar = SPACE;
  250.     lreset(i,j,SECRET);
  251.     lset(i, j, CHANGED);
  252.     dodrawspot(i,j);
  253.       }
  254.     }
  255.   levelrefresh();
  256. }
  257.  
  258. void aggravate()
  259. {
  260.   pml tm;
  261.  
  262.   for (tm=Level->mlist;tm!=NULL;tm=tm->next){
  263.     m_status_set(tm->m,AWAKE);
  264.     m_status_set(tm->m,HOSTILE);
  265.   }
  266. }
  267.  
  268.  
  269.  
  270.  
  271. void learnspell(blessing)
  272. int blessing;
  273. {
  274.   int i,spell,done=FALSE;
  275.   if (blessing < 0) {
  276.     for(i=NUMSPELLS;((i>-1) && (! done));i--)
  277.       if (Spells[i].known) {
  278.     done = TRUE;
  279.     Objects[SCROLLID+1].known = TRUE;
  280.     mprint("You feel forgetful.");
  281.     Spells[i].known = FALSE;
  282.       }
  283.     if (i == ABORT)
  284.       mprint("You feel fortunate.");
  285.   }
  286.   else {
  287.     Objects[SCROLLID+1].known = TRUE;
  288.     spell = random_range(NUMSPELLS);
  289.     print1("Spell Research");
  290.     if ((random_range(4*Spells[spell].powerdrain)+
  291.      Spells[spell].powerdrain) <
  292.     (4*Player.iq+8*Player.level)) {
  293.       nprint1(" -- Research successful: ");
  294.       nprint1(spellid(spell));
  295.       if (Spells[spell].known) {
  296.     print2("...is now easier to cast.");
  297.     Spells[spell].powerdrain = ((int) ((Spells[spell].powerdrain+1)/2));
  298.       }
  299.       else {
  300.     print2("...is added to your repertoire");
  301.     Spells[spell].known = TRUE;
  302.     gain_experience(Spells[spell].powerdrain*10);
  303.       }
  304.     }
  305.     else nprint1(" -- Research unsuccessful.");
  306.   }
  307. }
  308.  
  309.  
  310. void amnesia()
  311. {
  312.   int i,j;
  313.   for (j=0;j<LENGTH;j++)
  314.     for (i=0;i<WIDTH;i++)
  315.       lreset(i,j,SEEN);
  316.  
  317.   erase_level();
  318.   drawvision(Player.x,Player.y);
  319. }
  320.  
  321.  
  322. /*affects player only */
  323. void level_drain(levels,source)
  324. int levels;
  325. char *source;
  326. {
  327.   int decrement = ((int) (Player.maxhp / (Player.level+1)));
  328.  
  329.   Player.level -= levels;
  330.  
  331.   Player.maxhp -= (levels * decrement);
  332.   Player.hp -= (levels * decrement);
  333.  
  334.   if ((Player.hp < 1) || (Player.level < 0))
  335.     p_death(source);
  336. }
  337.  
  338.  
  339.  
  340.  
  341. void disrupt(x,y,amount)
  342. int x,y,amount;
  343. {
  344.   struct monster *target;
  345.  
  346.   if ((x ==Player.x) && (y==Player.y)) {
  347.     mprint("You feel disrupted!");
  348.     p_damage(amount,NORMAL_DAMAGE,"magical disruption");
  349.   }
  350.   else {
  351.     target = Level->site[x][y].creature;
  352.     if (target != NULL) {
  353.       if (target->uniqueness == COMMON) {
  354.     strcpy(Str1,"The ");
  355.     strcat(Str1,target->monstring);
  356.       }
  357.       else strcpy(Str1,target->monstring);
  358.       if (! m_immunityp(target,NORMAL_DAMAGE)) {
  359.     strcat(Str1," was blasted!");
  360.     mprint(Str1);
  361.     m_damage(target,amount,NORMAL_DAMAGE);
  362.     target->wakeup = 0;
  363.       }
  364.       else {
  365.     strcat(Str1," does not seem affected.");
  366.     mprint(Str1);
  367.       }
  368.     }
  369.   }
  370. }
  371.  
  372.  
  373.  
  374.  
  375. void disintegrate(x,y)
  376. int x,y;
  377. {
  378.   struct monster *target;
  379.   if (! inbounds(x,y)) mprint("You feel a sense of wastage.");
  380.   else if ((x==Player.x)&&(y==Player.y)) {
  381.     if (Player.possessions[O_CLOAK] != NULL) {
  382.       mprint("Your cloak disintegrates!");
  383.       dispose_lost_objects(1,Player.possessions[O_CLOAK]);
  384.     }
  385.     else if (Player.possessions[O_ARMOR] != NULL) {
  386.       mprint("Your armor disintegrates!");
  387.       dispose_lost_objects(1,Player.possessions[O_ARMOR]);
  388.     }
  389.     else {
  390.       mprint("Uh, oh....");
  391.       mprint("Zzzap! You've been disintegrated!");
  392.       p_damage(250,UNSTOPPABLE,"disintegration");
  393.     }
  394.   }
  395.   else {
  396.     if (!view_los_p(Player.x, Player.y, x, y))
  397.       setgamestatus(SUPPRESS_PRINTING);
  398.     if ((target = Level->site[x][y].creature) != NULL) {
  399.       if (target->uniqueness == COMMON) {
  400.     strcpy(Str1,"The ");
  401.     strcat(Str1,target->monstring);
  402.       }
  403.       else strcpy(Str1,target->monstring);
  404.       strcat(Str1," disintegrates!");
  405.       mprint(Str1);
  406.       m_damage(target,100,UNSTOPPABLE);
  407.       if (target->hp > 0) mprint("It was partially protected by its armor.");
  408.     }
  409.     else if (Level->site[x][y].locchar == ALTAR) {
  410.       mprint("Zzzzap! the altar seems unaffected...");
  411.       mprint("But an angry deity retaliates....");
  412.       disintegrate(Player.x,Player.y);
  413.     }
  414.     else if (Level->site[x][y].p_locf == L_TRAP_PIT) {
  415.       if (Current_Environment == Current_Dungeon) {
  416.     mprint("A hole is blasted in the base of the pit!");
  417.     Level->site[x][y].locchar = TRAP;
  418.     Level->site[x][y].p_locf = L_TRAP_DOOR;
  419.     Level->site[x][y].aux = S_DISINTEGRATE;
  420.     lset(x, y, CHANGED);
  421.       }
  422.       else mprint("The hole just gets deeper....");
  423.     }
  424.     else if (Level->site[x][y].locchar == FLOOR) {
  425.       mprint("You zap a hole in the floor!");
  426.       Level->site[x][y].locchar = TRAP;
  427.       Level->site[x][y].p_locf = L_TRAP_PIT;
  428.       lset(x, y, CHANGED);
  429.     }
  430.     else if ((Level->site[x][y].locchar == WALL) ||
  431.          (Level->site[x][y].locchar == OPEN_DOOR) ||
  432.          (Level->site[x][y].locchar == CLOSED_DOOR) ||
  433.          (Level->site[x][y].locchar == PORTCULLIS) ||
  434.          (Level->site[x][y].locchar == STATUE)) {
  435.       mprint("The site is reduced to rubble!");
  436.       if (Level->site[x][y].locchar == WALL)
  437.     tunnelcheck();
  438.       Level->site[x][y].p_locf = L_RUBBLE;
  439.       Level->site[x][y].locchar = RUBBLE;
  440.       lreset(x,y,SECRET);
  441.       lset(x, y, CHANGED);
  442.     }
  443.     else if ((Level->site[x][y].locchar == RUBBLE) ||
  444.          (Level->site[x][y].locchar == TRAP)) {
  445.       mprint("The site is blasted clear!");
  446.       Level->site[x][y].p_locf = L_NO_OP;
  447.       Level->site[x][y].locchar = FLOOR;
  448.       lreset(x,y,SECRET);
  449.       lset(x, y, CHANGED);
  450.     }
  451.     else if (Level->site[x][y].locchar == HEDGE) {
  452.       if (Level->site[x][y].p_locf == L_TRIFID) {
  453.     mprint("The trifid screams as it disintgrates!");
  454.     gain_experience(50);
  455.     Level->site[x][y].p_locf = L_NO_OP;
  456.     Level->site[x][y].locchar = FLOOR;
  457.     lreset(x,y,SECRET);
  458.     lset(x, y, CHANGED);
  459.       }
  460.       else {
  461.     mprint("The hedge is blasted away!");
  462.     Level->site[x][y].p_locf = L_NO_OP;
  463.     Level->site[x][y].locchar = FLOOR;
  464.     lreset(x,y,SECRET);
  465.     lset(x, y, CHANGED);
  466.       }
  467.     }
  468.     else mprint("The blast has no effect.");
  469.     if (!view_los_p(Player.x, Player.y, x, y))
  470.       resetgamestatus(SUPPRESS_PRINTING);
  471.     else
  472.       plotspot(x, y, TRUE);
  473.   }
  474. }
  475.  
  476. void acid_cloud()
  477. {
  478.   mprint("You are caught in an acid cloud!  ");
  479.   if (Player.possessions[O_CLOAK] != NULL) {
  480.     (void) damage_item(Player.possessions[O_CLOAK]);
  481.     mprint("You are burned by acid.");
  482.     p_damage(3,ACID,"an acid cloud");
  483.   }
  484.   else if (Player.possessions[O_ARMOR] != NULL) {
  485.     mprint("You are burned by acid.");
  486.     p_damage(3,ACID,"an acid cloud");
  487.     (void) damage_item(Player.possessions[O_ARMOR]);
  488.   }
  489.   else if (p_immune(ACID))
  490.   {
  491.     mprint("You resist the effects!");
  492.     return;
  493.   }
  494.   else {
  495.     mprint("The acid eats away at your bare skin!");
  496.     p_damage(25,ACID,"an acid cloud");
  497.   }
  498. }
  499.  
  500.  
  501.  
  502. /* teleport player */
  503. void p_teleport(type)
  504. int type;
  505. {
  506.   int x=Player.x,y=Player.y;
  507.   drawspot(x,y);
  508.   if (type < 0) {
  509.     x = random_range(WIDTH);
  510.     y = random_range(LENGTH);
  511.     if ((Level->site[x][y].locchar != FLOOR) &&
  512.     (Level->site[x][y].locchar != OPEN_DOOR)) {
  513.       mprint("You teleported into a solid object....");
  514.       mprint("You are dead!");
  515.       p_death("teleportation into a solid object");
  516.     }
  517.     else {
  518.       Player.x = x;
  519.       Player.y = y;
  520.     }
  521.   }
  522.   else if (type == 0)
  523.     findspace(&(Player.x),&(Player.y),-1);
  524.   else {
  525.     setspot(&Player.x,&Player.y);
  526.     if ((Level->site[Player.x][Player.y].locchar != FLOOR) ||
  527.     (Level->site[Player.x][Player.y].creature != NULL)) {
  528.       mprint("You feel deflected.");
  529.       p_teleport(0);
  530.     }
  531.   }
  532.   screencheck(Player.y);
  533.   roomcheck();
  534. }
  535.  
  536.  
  537. void p_poison(toxicity)
  538. int toxicity;
  539. {
  540.   mprint("You feel sick.");
  541.   if (! p_immune(POISON))
  542.     Player.status[POISONED]+=toxicity;
  543.   else mprint("The sickness fades!");
  544.   showflags();
  545. }
  546.  
  547. void apport(blessing)
  548. int blessing;
  549. {
  550.   int i,index,x=Player.x,y=Player.y;
  551.   if (blessing > -1) {
  552.     mprint("Apport from:");
  553.     setspot(&x,&y);
  554.     if (Level->site[x][y].things != NULL) {
  555.       pickup_at(x,y);
  556.       plotspot(x, y, TRUE);
  557.     }
  558.     else mprint("There's nothing there to apport!");
  559.   }
  560.   else {
  561.     mprint("You have a sense of loss.");
  562.     for(i=0;i<abs(blessing);i++) {
  563.       index = random_item();
  564.       if (index != ABORT) {
  565.     drop_at(x,y,Player.possessions[index]);
  566.     dispose_lost_objects(Player.possessions[index]->number,
  567.       Player.possessions[index]);
  568.       }
  569.     }
  570.   }
  571. }
  572.  
  573.  
  574. void strategic_teleport(blessing)
  575. int blessing;
  576. {
  577.   int new_env;
  578.  
  579.   mprint("Magic portals open up all around you!");
  580.   if (blessing < 0) {
  581.     morewait();
  582.     mprint("You are dragged into one!");
  583.     change_environment(E_COUNTRYSIDE);
  584.     do {
  585.       Player.x = random_range(WIDTH);
  586.       Player.y = random_range(LENGTH);
  587.     } while(Country[Player.x][Player.y].base_terrain_type == CHAOS_SEA);
  588.   }
  589.   else {
  590.     mprint("Below each portal is a caption. Enter which one:");
  591.     menuclear();
  592.     menuprint("a: Rampart\n");
  593.     menuprint("b: Village of Star View\n");
  594.     menuprint("c: Village of Woodmere\n");
  595.     menuprint("d: Village of Stormwatch\n");
  596.     menuprint("e: Village of Thaumaris\n");
  597.     menuprint("f: Village of Skorch\n");
  598.     menuprint("g: Village of Whorfen\n");
  599.     menuprint("h: Temple of the Noose\n");
  600.     menuprint("i: The Parthenon\n");
  601.     menuprint("j: Temple of the Black Hand\n");
  602.     menuprint("k: Temple of the Hidden Moon\n");
  603.     menuprint("l: WoodHenge\n");
  604.     menuprint("m: Temple of Destiny\n");
  605.     menuprint("n: HellWell Volcano\n");
  606.     menuprint("ANYTHING ELSE: Avoid entering a portal.");
  607.     showmenu();
  608.     switch((char) mcigetc()) {
  609.     case 'a': 
  610.       change_environment(E_COUNTRYSIDE); 
  611.       Player.x = 27;
  612.       Player.y = 19;
  613.       break;
  614.     case 'b':
  615.       change_environment(E_COUNTRYSIDE);
  616.       Player.x = 56;
  617.       Player.y = 5;
  618.       break;
  619.     case 'c':
  620.       change_environment(E_COUNTRYSIDE);
  621.       Player.x = 35;
  622.       Player.y = 11;
  623.       break;
  624.     case 'd':
  625.       change_environment(E_COUNTRYSIDE);
  626.       Player.x = 10;
  627.       Player.y = 40;
  628.       break;
  629.     case 'e':
  630.       change_environment(E_COUNTRYSIDE);
  631.       Player.x = 7;
  632.       Player.y = 6;
  633.       break;
  634.     case 'f':
  635.       change_environment(E_COUNTRYSIDE);
  636.       Player.x = 41;
  637.       Player.y = 43;
  638.       break;
  639.     case 'g':
  640.       change_environment(E_COUNTRYSIDE);
  641.       Player.x = 20;
  642.       Player.y = 41;
  643.       break;
  644.     case 'h':
  645.       change_environment(E_COUNTRYSIDE);
  646.       Player.x = 22;
  647.       Player.y = 30;
  648.       break;
  649.     case 'i':
  650.       change_environment(E_COUNTRYSIDE);
  651.       Player.x = 51;
  652.       Player.y = 11;
  653.       break;
  654.     case 'j':
  655.       change_environment(E_COUNTRYSIDE);
  656.       Player.x = 45;
  657.       Player.y = 45;
  658.       break;
  659.     case 'k':
  660.       change_environment(E_COUNTRYSIDE);
  661.       Player.x = 19;
  662.       Player.y = 46;
  663.       break;
  664.     case 'l':
  665.       change_environment(E_COUNTRYSIDE);
  666.       Player.x = 32;
  667.       Player.y = 5;
  668.       break;
  669.     case 'm':
  670.       change_environment(E_COUNTRYSIDE);
  671.       Player.x = 49;
  672.       Player.y = 59;
  673.       break;
  674.     case 'n':
  675.       change_environment(E_COUNTRYSIDE);
  676.       Player.x = 30;
  677.       Player.y = 58;
  678.       break;
  679.     default:
  680.       if (gamestatusp(CHEATED)) {
  681.     mprint("Enter environment number: ");
  682.     new_env = (int) parsenum();
  683.     change_environment(new_env);
  684.       }
  685.     }
  686.     xredraw();
  687.     if (gamestatusp(LOST)) {
  688.       print1("You know where you are now.");
  689.       resetgamestatus(LOST);
  690.       Precipitation = 0;
  691.     }
  692.   }
  693.   setlastxy(Player.x, Player.y);
  694.   screencheck(Player.y);
  695.   drawvision(Player.x,Player.y);
  696.   if (Current_Environment == E_COUNTRYSIDE)
  697.     terrain_check(FALSE);
  698. }
  699.  
  700.  
  701.  
  702. void hero(blessing)
  703. int blessing;
  704. {
  705.   if (blessing > -1) {
  706.       mprint("You feel super!");
  707.       Player.status[HERO] += random_range(5)+1+blessing;
  708.       calc_melee();
  709.     }
  710.   else {
  711.     Player.status[HERO]=0;
  712.     calc_melee();
  713.     mprint("You feel cowardly.");
  714.     level_drain(abs(blessing),"a potion of cowardice");
  715.   }
  716. }
  717.  
  718.  
  719. void levitate(blessing)
  720. int blessing;
  721. {
  722.   if (blessing > -1) {
  723.     if (gamestatusp(MOUNTED)) 
  724.       mprint("You have a strange feeling of lightness in your saddle.");
  725.     else {
  726.       mprint("You start to float a few inches above the floor.");
  727.       mprint("You discover you can easily control your altitude...");
  728.       mprint("(Note use of '@' command may be useful while levitating)");
  729.       Player.status[LEVITATING] += random_range(5)+1+blessing;
  730.     }
  731.   }
  732.   else mprint("Nothing much happens.");
  733. }
  734.  
  735.  
  736. /* has effect of switching between 1st level and deepest level attained */
  737. void level_return()
  738. {
  739.   if (Current_Environment == Current_Dungeon) {
  740.     mprint("The vortex of mana carries you off!");
  741.     if (Level->depth > 1)
  742.       change_level(Level->depth,1,FALSE);
  743.     else change_level(Level->depth,deepest[Current_Environment],FALSE);
  744.   }
  745.   else if (Current_Environment == E_COUNTRYSIDE) {
  746.     mprint("A mysterious force wafts you back home!");
  747.     Player.x = 27;
  748.     Player.y = 19;
  749.     screencheck(Player.y);
  750.     drawvision(Player.x,Player.y);
  751.     locprint("Back Outside Rampart.");
  752.   }
  753.   else mprint("A feeble vortex of magic swirls by and has no further effect.");
  754. }
  755.  
  756.  
  757. void cure(blessing)
  758. int blessing;
  759. {
  760.   int happened = FALSE;
  761.   if (blessing > -1) {
  762.     if (Player.status[DISEASED]) {
  763.       Player.status[DISEASED]=0;
  764.       mprint("You feel hygienic!");
  765.       happened = TRUE;
  766.     }
  767.     if (Player.status[POISONED]) {
  768.       Player.status[POISONED] -= 5+blessing*10;
  769.       if (Player.status[POISONED] > 0)
  770.     mprint("The effect of the poison has been reduced.");
  771.       else {
  772.     Player.status[POISONED] = 0;
  773.     mprint("The poison has been purged from your system.");
  774.       }
  775.       happened = TRUE;
  776.     }
  777.     if (Player.status[BLINDED]) {
  778.       Player.status[BLINDED]=0;
  779.       happened = TRUE;
  780.       mprint("Cobwebs clear from before your eyes.");
  781.     }
  782.     if (! happened) mprint("Nothing much happens.");
  783.   }
  784.   else disease(12);
  785.   showflags();
  786. }
  787.  
  788. void disease(amount)
  789. int amount;
  790. {
  791.   mprint("You feel ill.");
  792.   if (! Player.immunity[INFECTION]) {
  793.     mprint("You begin to shiver with ague.");
  794.     Player.status[DISEASED]+=random_range(amount*2)+1;
  795.   }
  796.   else mprint("The illness fades.");
  797. }
  798.  
  799. void truesight(blessing)
  800. int blessing;
  801. {
  802.   if (blessing > -1) {
  803.     Player.status[TRUESIGHT]+=random_range(10)+1;
  804.     mprint("You feel sharp.");
  805.   }
  806.   else {
  807.     Player.status[BLINDED]+=random_range(10)+1;
  808.     mprint("You've been blinded!");
  809.   }
  810. }
  811.  
  812.  
  813.  
  814. void dispel(blessing)
  815. int blessing;     
  816. {
  817.   int i,x=Player.x,y=Player.y;
  818.   if (blessing > -1) {
  819.     setspot(&x,&y);
  820.     if ((x==Player.x)&&(y==Player.y)) {
  821.       for(i=0;i<MAXITEMS;i++) {
  822.     if (Player.possessions[i]!=NULL)
  823.       if ((Player.possessions[i]->used) &&
  824.           (Player.possessions[i]->blessing < 0)) {
  825.         if (blessing+1 + Player.possessions[i]->blessing >=0) {
  826.           mprint("You hear a sighing sound from");
  827.           mprint(itemid(Player.possessions[i]));
  828.           Player.possessions[i]->blessing = 0;
  829.         }
  830.         else {
  831.           mprint("You hear dark laughter from");
  832.           mprint(itemid(Player.possessions[i]));
  833.         }
  834.       }
  835.       }
  836.     }
  837.     else if (Level->site[x][y].creature != NULL) {
  838.       if (Level->site[x][y].creature->level < blessing * 3) {
  839.     Level->site[x][y].creature->specialf = M_NO_OP;
  840.     if (Level->site[x][y].creature->meleef != M_NO_OP)
  841.       Level->site[x][y].creature->meleef = M_MELEE_NORMAL;
  842.     Level->site[x][y].creature->strikef = M_NO_OP;
  843.     Level->site[x][y].creature->immunity=0;
  844.     m_status_reset(Level->site[x][y].creature,M_INVISIBLE);    
  845.     m_status_reset(Level->site[x][y].creature,INTANGIBLE);
  846.       }
  847.       else mprint("The monster ignores the effect!");
  848.     }
  849.     else if ((Level->site[x][y].p_locf == L_TRAP_FIRE) ||
  850.          (Level->site[x][y].p_locf == L_STATUE_WAKE) ||
  851.          (Level->site[x][y].p_locf == L_TRAP_TELEPORT) ||
  852.          (Level->site[x][y].p_locf == L_TRAP_DISINTEGRATE)) {
  853.       Level->site[x][y].p_locf = L_NO_OP;
  854.       if (Level->site[x][y].locchar == TRAP)
  855.     Level->site[x][y].locchar = FLOOR;
  856.       lset(x, y, CHANGED);
  857.     }
  858.     else if (Level->site[x][y].p_locf == L_MAGIC_POOL)
  859.       Level->site[x][y].p_locf = L_WATER;
  860.     else mprint("Nothing much seems to happen.");
  861.   }
  862.   else {
  863.     mprint("A smell of ozone and positive ions fills the air..");
  864.     if (Player.status[ACCURACY] && (Player.status[ACCURACY] < 1000))
  865.       Player.status[ACCURACY]=1;
  866.     if (Player.status[DISPLACED]&&(Player.status[DISPLACED] < 1000))
  867.     Player.status[DISPLACED]=1;
  868.     if (Player.status[HASTED]&&(Player.status[HASTED] < 1000))
  869.       Player.status[HASTED]=1;
  870.     if (Player.status[BREATHING]&&(Player.status[BREATHING] < 1000))
  871.       Player.status[BREATHING]=1;
  872.     if (Player.status[INVISIBLE]&&(Player.status[INVISIBLE] < 1000))
  873.     Player.status[INVISIBLE]=1;
  874.     if (Player.status[REGENERATING]&&(Player.status[REGENERATING] < 1000))
  875.       Player.status[REGENERATING]=1;
  876.     if (Player.status[ALERT]&&(Player.status[ALERT] < 1000))
  877.     Player.status[ALERT]=1;
  878.     if (Player.status[HERO]&&(Player.status[HERO] < 1000))
  879.     Player.status[HERO]=1;
  880.     if (Player.status[LEVITATING]&&(Player.status[LEVITATING] < 1000))
  881.     Player.status[LEVITATING]=1;
  882.     if (Player.status[ACCURATE]&&(Player.status[ACCURATE] < 1000))
  883.     Player.status[ACCURATE]=1;
  884.     if (Player.status[TRUESIGHT]&&(Player.status[TRUESIGHT] < 1000))
  885.     Player.status[TRUESIGHT]=1;
  886.     tenminute_status_check();
  887.   }
  888. }
  889.  
  890.  
  891. void polymorph(blessing)
  892. int blessing;     
  893. {
  894.   int x=Player.x,y=Player.y,newmonster;
  895.   struct monster *m;
  896.   setspot(&x,&y);
  897.   if ((x==Player.x)&&(y==Player.y)) {
  898.     mprint("You enjoy your new life as a");
  899.     mprint(Monsters[random_range(NUMMONSTERS)].monstring);
  900.     mprint("But your game is over....");
  901.     p_death("polymorphing oneself");
  902.   }
  903.   else if ((m=Level->site[x][y].creature) == NULL)
  904.     mprint("Nothing happens.");
  905.   else {
  906.     if (m_immunityp(m,OTHER_MAGIC) || (m->level > random_range(12))) {
  907.       strcpy(Str1,"The ");
  908.       strcat(Str1,m->monstring);
  909.       strcat(Str1," resists the change!");
  910.       m_status_set(m,HOSTILE);
  911.     }
  912.     else {
  913.       if (blessing < 0) {
  914.     do newmonster = random_range(NUMMONSTERS);
  915.     while ((newmonster == ML0+4) ||
  916.            (newmonster == ML7+3) ||
  917.            (Monsters[newmonster].level <= m->level) ||
  918.            (Monsters[newmonster].uniqueness != COMMON));
  919.       }
  920.       else {
  921.     do newmonster = random_range(NUMMONSTERS);
  922.     while ((newmonster == ML0+4) ||
  923.            (newmonster == ML7+3) ||
  924.            (Monsters[newmonster].uniqueness != COMMON));
  925.       }
  926.       m->id = Monsters[newmonster].id;
  927.       m->hp = max(m->hp,Monsters[newmonster].id);
  928.       m->speed = Monsters[newmonster].speed;
  929.       m->hit = Monsters[newmonster].hit;
  930.       m->ac = Monsters[newmonster].ac;
  931.       m->dmg = Monsters[newmonster].dmg;
  932.       m->sense = Monsters[newmonster].sense;
  933.       m->wakeup = Monsters[newmonster].wakeup;
  934.       m->level = max(m->level,Monsters[newmonster].level);
  935.       m->status = Monsters[newmonster].status;
  936.       m->immunity = (m->immunity | Monsters[newmonster].immunity);
  937.       m->xpv = max(m->xpv,Monsters[newmonster].wakeup);
  938.       m->transformid = Monsters[newmonster].transformid;
  939.       m->corpsevalue = Monsters[newmonster].corpsevalue;
  940.       m->corpseweight = Monsters[newmonster].corpseweight;
  941.       m->monchar = Monsters[newmonster].monchar;
  942.       m->meleestr = Monsters[newmonster].meleestr;
  943.       m->monstring = Monsters[newmonster].monstring;
  944.       m->corpsestr = Monsters[newmonster].corpsestr;
  945.       m->talkf = Monsters[newmonster].talkf;
  946.       m->movef = Monsters[newmonster].movef;
  947.       m->meleef = Monsters[newmonster].meleef;
  948.       m->strikef = Monsters[newmonster].strikef;
  949.       m->specialf = Monsters[newmonster].specialf;
  950.       m_status_set(m,HOSTILE);
  951.     }
  952.   }
  953. }
  954.  
  955.  
  956.  
  957.  
  958. void hellfire(x,y,blessing)
  959. int x,y,blessing;
  960. {
  961.   struct monster *m;
  962.   if ((x==Player.x)&&(y==Player.y)) {
  963.     mprint("You have been completely annihilated. Congratulations.");
  964.     p_death("hellfire");
  965.   }
  966.   else if ((m=Level->site[x][y].creature) == NULL) {
  967.     mprint("The gods are angry over your waste of power...");
  968.     level_drain(5,"indiscriminate use of hellfire");
  969.   }
  970.   else {
  971.     mprint("The monster writhes in the flames...");
  972.     if (blessing < 0) {
  973.       mprint("...and appears stronger.");
  974.       morewait();
  975.       mprint("Much stronger.");
  976.       m->hp += 1000;
  977.       m->hit +=20;
  978.       m->dmg += 100;
  979.       m_status_set(m,HOSTILE);
  980.     }
  981.     else {
  982.       if (m->uniqueness == COMMON) {
  983.     mprint("and is utterly annihilated. Only a greasy spot remains...");
  984.     m->corpsestr = "a greasy spot";
  985.     m->id = 0;
  986.     free_objlist(m->possessions);
  987.     m->possessions = NULL;
  988.       }
  989.       else
  990.     mprint("and dies, cursing your name and the uncaring gods....");
  991.       m_death(m);
  992.     }
  993.   }
  994. }
  995.  
  996.  
  997. void drain(blessing)
  998. int blessing;
  999. {
  1000.   int x=Player.x,y=Player.y;
  1001.   struct monster *m;
  1002.   setspot(&x,&y);
  1003.   mprint("You begin to drain energy...");
  1004.   if ((x==Player.x)&&(y==Player.y)) {
  1005.     mprint("You drain your own energy....");
  1006.     mprint("Uh, oh, positive feedback....");
  1007.     level_drain(Player.level,"self-vampirism");
  1008.   }
  1009.   else if ((m=Level->site[x][y].creature) != NULL) {
  1010.     if ((blessing > -1) && (! m_immunityp(m,NEGENERGY))) {
  1011.       mprint("The monster seems weaker...");
  1012.       m_damage(m,m->level*m->level,NEGENERGY);
  1013.       m->hit = max(m->hit - m->level, 1);
  1014.       m->dmg = max(m->dmg - m->level*m->level, 1);
  1015.       m->ac = max(m->ac - m->level, 1);
  1016.       m->level = max(1,m->level-1);
  1017.       mprint("You feel stronger...");
  1018.       gain_experience(m->level*5);
  1019.       Player.hp+=(m->level*m->level / 2);
  1020.     }
  1021.     else {
  1022.       mprint("The effect reverses itself!");
  1023.       mprint("The monster seems stronger...");
  1024.       m->hp+=Player.level*Player.level;
  1025.       m->hit += Player.level;
  1026.       m->dmg += Player.level*Player.level;
  1027.       m->ac += Player.level;
  1028.       m->level++;
  1029.       mprint("You feel weaker...");
  1030.       Player.mana = min(0,Player.level*Player.level);
  1031.       level_drain(m->level,"negative energy conflict");
  1032.     }
  1033.   }
  1034.   else if (blessing < 0) {
  1035.     mprint("You seem to lose energy, instead of gaining it!");
  1036.     level_drain(3,"reversed energy drain");
  1037.   }
  1038.   else if (Level->site[x][y].locchar == ALTAR) {
  1039.     mprint("The altar collapses in on itself....");
  1040.     Level->site[x][y].locchar = ABYSS;
  1041.     Level->site[x][y].p_locf = L_ABYSS;
  1042.     lset(x, y, CHANGED);
  1043.     if (! Player.patron) {
  1044.       mprint("You drain some theurgic energy from the altar....");
  1045.       gain_experience(40);
  1046.       Player.hp += 20;
  1047.       Player.pow+=2;
  1048.     }
  1049.     if (Level->site[x][y].aux == Player.patron) {
  1050.       mprint("Your deity is enraged.");
  1051.       mprint("You are struck by godsfire.");
  1052.       p_damage(Player.hp-1,UNSTOPPABLE,"godsfire");
  1053.       mprint("You feel atheistic.");
  1054.       Player.patron = -1;
  1055.       Player.rank[PRIESTHOOD] = 0;
  1056.     }
  1057.     else {
  1058.       mprint("You feel the wrath of a god....");
  1059.       p_damage(random_range(Player.level*10),UNSTOPPABLE,"divine wrath");
  1060.       if (Player.patron != 0) {
  1061.     mprint("Your deity doesn't seem to mind your action, though.");
  1062.     gain_experience(100);
  1063.       }
  1064.     }
  1065.   }
  1066.   else {
  1067.     mprint("You drain some energy from the ambient megaflow.");
  1068.     Player.hp++;
  1069.   }
  1070. }
  1071.  
  1072. void sanctuary()
  1073. {
  1074.   if (Level->environment == E_TEMPLE) 
  1075.     mprint("Odd, the spell has no effect. I wonder why.");
  1076.   else {
  1077.     mprint("You're standing on sacred ground!");
  1078.     Player.sx = Player.x;
  1079.     Player.sy = Player.y;
  1080.   }
  1081. }
  1082.  
  1083. void shadowform()
  1084. {
  1085.   if (!Player.status[SHADOWFORM]) {
  1086.     mprint("You feel like a shadow.");
  1087.     Player.immunity[NORMAL_DAMAGE]+=Player.level;
  1088.     Player.immunity[ACID]+=Player.level;
  1089.     Player.immunity[THEFT]+=Player.level;
  1090.     Player.immunity[INFECTION]+=Player.level;
  1091.     Player.status[SHADOWFORM]+=Player.level;
  1092.   }
  1093.   else {
  1094.     mprint("You feel even more shadowy.");
  1095.     Player.immunity[NORMAL_DAMAGE]++;
  1096.     Player.immunity[ACID]++;
  1097.     Player.immunity[THEFT]++;
  1098.     Player.immunity[INFECTION]++;
  1099.     Player.status[SHADOWFORM]++;
  1100.   }
  1101. }
  1102.  
  1103. void illuminate(blessing)
  1104. int blessing;
  1105. {
  1106.   int r=Level->site[Player.x][Player.y].roomnumber;
  1107.   if (blessing > -1) {
  1108.     if (r > ROOMBASE) {
  1109.       if (loc_statusp(Player.x,Player.y,LIT))
  1110.     mprint("A glow surrounds you.");
  1111.       else {
  1112.     mprint("The room lights up!");
  1113.     Player.status[ILLUMINATION]+=blessing+3;
  1114.     spreadroomlight(Player.x,
  1115.             Player.y,
  1116.             Level->site[Player.x][Player.y].roomnumber);
  1117.       }
  1118.     }
  1119.     else mprint("You see a faint glimmer of light which quickly fades.");
  1120.   }
  1121.   else {
  1122.     if (r > ROOMBASE) {
  1123.       if (! loc_statusp(Player.x,Player.y,LIT))
  1124.     mprint("Nothing much happens.");
  1125.       else {
  1126.     mprint("The room darkens!");
  1127.     spreadroomdark(Player.x,
  1128.                Player.y,
  1129.                Level->site[Player.x][Player.y].roomnumber);
  1130.       }
  1131.     }
  1132.     else mprint("The gloom thickens for a moment.");
  1133.   }
  1134. }
  1135.  
  1136.  
  1137. void drain_life(amount)
  1138. int amount;
  1139. {
  1140.   amount = abs(amount);
  1141.   mprint("You feel cold!");
  1142.   if (p_immune(NEGENERGY))
  1143.     mprint("... but the feeling quickly fades.");
  1144.   else {
  1145.     if (random_range(2)) {
  1146.       mprint("The coldness spreads throughout your body...");
  1147.       Player.str-=amount;
  1148.       Player.con-=amount;
  1149.       if ((Player.str < 3) || (Player.con < 3)) {
  1150.     mprint("You suffer a fatal heart attack!!!");
  1151.     Player.hp = 0;
  1152.     strcpy(Str2,"a coronary");
  1153.     p_death(Str2);
  1154.       }
  1155.     }
  1156.     else {
  1157.       mprint("The coldness saps your very soul...");
  1158.       strcpy(Str2,"soul destruction");
  1159.       level_drain(amount,Str2);
  1160.     }
  1161.   }
  1162. }
  1163.  
  1164.  
  1165. void inflict_fear(x,y)
  1166. int x,y;
  1167. {
  1168.   struct monster *m;
  1169.   if ((Player.x == x) && (Player.y == y)) {
  1170.     mprint("You shudder with otherworldly dread.");
  1171.     if (Player.immunity[FEAR] > 0)
  1172.       mprint("You brace up and face your fear like a hero!");
  1173.     else {
  1174.       mprint("You panic!");
  1175.       Player.status[AFRAID]+=10;
  1176.     }
  1177.   }
  1178.   else if ((m = Level->site[x][y].creature) != NULL) {
  1179.     if (m->uniqueness == COMMON) {
  1180.       strcpy(Str2,"The ");
  1181.       strcat(Str2,m->monstring);
  1182.     }
  1183.     else strcpy(Str2,m->monstring);
  1184.     m->speed = max(2,m->speed-1);
  1185.     if (m_immunityp(m,FEAR)) 
  1186.       strcat(Str2,"seems enraged!");
  1187.     else {
  1188.       strcat(Str2,"is terrorized!");
  1189.       m_dropstuff(m);
  1190.       if (m_statusp(m,MOBILE))
  1191.     m->movef = M_MOVE_SCAREDY;
  1192.     }
  1193.   }
  1194.   else mprint("A thrill of fear tickles your spine ... and passes.");
  1195. }
  1196.  
  1197.  
  1198.  
  1199.  
  1200. /*Turns on deflection status for the player */
  1201. void deflection(blessing)
  1202. int blessing;
  1203. {
  1204.   if (blessing > -1) {
  1205.       mprint("You feel buffered.");
  1206.       Player.status[DEFLECTION] = blessing + random_range(6);
  1207.     }
  1208.   else {
  1209.     mprint("You feel vulnerable");
  1210.     Player.status[VULNERABLE] += random_range(6) - blessing;
  1211.   }
  1212. }
  1213.